;================================================================
;  unpack.s
;               Unpacking data with a primitive LZW algorithm
;
;================================================================
;
; 25thanni, a demo dedicated to the 25th anniversary of the ZX81.
;
; (c)2006 Bodo Wenzel
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License as
; published by the Free Software Foundation; either version 2 of
; the License, or (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public
; License along with this program; if not, write to the Free
; Software Foundation Inc., 59 Temple Place, Suite 330, Boston,
; MA 02111-1307 USA
;================================================================

	.module	unpack

;= Constants ====================================================

ENTRY_SIZE	=	2
COUNT_BITS	=	4
COUNT_MASK	=	~0<<COUNT_BITS
MIN_COUNT	=	3

;= Program code =================================================

	.area	CODE

;- Unpacks data -------------------------------------------------
; BC	number of bytes
; DE	pointer to source
; HL	pointer to destination

unpack::
	ex	de,hl
	exx
	ld	b,#1
	exx
u_loop:
	ld	a,c
	or	b
	ret	z

	exx
	djnz	u_next

	exx
	dec	bc
	ld	a,(hl)
	inc	hl
	exx
	ld	b,#8
	ld	c,a		; fetch entry flags

u_next:
	rl	c
	exx
	jr	c,u_replica

	ldi			; copy from source
	jr	u_loop

u_replica:
	push	bc

	.if	ENTRY_SIZE-2
	.error	"Code depends on ENTRY_SIZE=2"
	.endif
	ld	c,(hl)
	inc	hl
	ld	a,(hl)
	and	#~COUNT_MASK
	ld	b,a
	ld	a,(hl)
	inc	hl
	xor	b
	.if	COUNT_BITS-4
	.error	"Code depends on COUNT_BITS=4"
	.endif
	rrca
	rrca
	rrca
	rrca

	push	hl

	ld	hl,#-MIN_COUNT
	sbc	hl,bc
	add	hl,de
	add	a,#MIN_COUNT
u_r_loop:
	ldi
	dec	a
	jr	nz,u_r_loop

	pop	hl
	pop	bc
	dec	bc
	dec	bc

	jr	u_loop

;= The end ======================================================
